package com.hexacta.hrs.web.struts.actions.feedbacks;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.vectrics.employee.Employee;
import org.vectrics.recruiter.job.JobFunction;
import org.vectrics.recruiter.job.JobTerm;

import com.hexacta.hrs.domain.employee.history.CareerRole;
import com.hexacta.hrs.domain.feedback.FeedbackPeriod;
import com.hexacta.hrs.domain.feedback.FeedbackPeriodResume;
import com.hexacta.hrs.securitygroups.PermissionNameConverter;
import com.hexacta.hrs.services.feedbacks.FeedbackPeriodService;
import com.hexacta.hrs.services.feedbacks.PeriodService;
import com.hexacta.hrs.services.staffing.EmployeeAssignmentService;
import com.hexacta.hrs.web.struts.actions.security.PermissionChecker;
import com.opensymphony.xwork2.ActionSupport;

public class FeedbackPeriodsAction extends ActionSupport implements ServletRequestAware {

    private static final long serialVersionUID = -7192248251486130798L;

    private FeedbackPeriodService feedbackPeriodService;

    private PeriodService periodService;

    private EmployeeAssignmentService employeeAssignmentService;

    private String message;

    private boolean alreadyCreated;

    private boolean periodOpen;

    private boolean gotAssignments;

    private String period;

    private List<FeedbackPeriodResume> feedbackPeriods;

    private HttpServletRequest request;

    private PermissionChecker permissionChecker = new PermissionChecker();

    private PermissionNameConverter permissionNameConverter = new PermissionNameConverter();

    public FeedbackPeriodService getFeedbackPeriodService() {
        return feedbackPeriodService;
    }

    public void setFeedbackPeriodService(final FeedbackPeriodService feedbackPeriodService) {
        this.feedbackPeriodService = feedbackPeriodService;
    }

    /**
     * @return the periodService
     */
    public PeriodService getPeriodService() {
        return periodService;
    }

    /**
     * @param periodService
     *            the periodService to set
     */
    public void setPeriodService(final PeriodService periodService) {
        this.periodService = periodService;
    }

    public EmployeeAssignmentService getEmployeeAssignmentService() {
        return employeeAssignmentService;
    }

    public void setEmployeeAssignmentService(final EmployeeAssignmentService employeeAssignmentService) {
        this.employeeAssignmentService = employeeAssignmentService;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(final String message) {
        this.message = message;
    }

    public boolean isAlreadyCreated() {
        return alreadyCreated;
    }

    public void setAlreadyCreated(final boolean alreadyCreated) {
        this.alreadyCreated = alreadyCreated;
    }

    public String getPeriod() {
        return period;
    }

    public void setPeriod(final String period) {
        this.period = period;
    }

    public List<FeedbackPeriodResume> getFeedbackPeriods() {
        return feedbackPeriods;
    }

    public void setFeedbackPeriods(final List<FeedbackPeriodResume> feedbackPeriods) {
        this.feedbackPeriods = feedbackPeriods;
    }

    @Override
    public String execute() throws Exception {

        alreadyCreated = feedbackPeriodService.validateIfCurrentFeedbackPeriodIsAlreadyCreated();
        periodOpen = periodService.existsOpenPeriod();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");

        gotAssignments = employeeAssignmentService.checkAssignmentByYear(sdf.format(new Date()));

        if (alreadyCreated) {
            setMessage("The current period (" + sdf.format(new Date()) + ") already has been created.");
        } else {
            if (periodOpen) {
                setMessage("You cannot create the period " + sdf.format(new Date()) + " until the last one is closed.");
            } else {
                setMessage("Press create button for create the period " + sdf.format(new Date()) + ".");
            }
        }
        if (!gotAssignments) {
            setMessage("There is not assignments for this year");
        }

        feedbackPeriods = feedbackPeriodService.getAllFeedbackPeriodResumes();

        return INPUT;
    }

    public String create() throws Exception {
        feedbackPeriodService.createActualFeedbackPeriod();
        return execute();
    }

    public boolean hasPermission(final String permission) {
        return getPermissionChecker().hasPermission(permission, request.getSession());
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    @Override
    public void setServletRequest(final HttpServletRequest request) {
        this.request = request;
    }

    public void setPermissionChecker(final PermissionChecker permissionChecker) {
        this.permissionChecker = permissionChecker;
    }

    public PermissionChecker getPermissionChecker() {
        return permissionChecker;
    }

    public void setPermissionNameConverter(final PermissionNameConverter permissionNameConverter) {
        this.permissionNameConverter = permissionNameConverter;
    }

    public PermissionNameConverter getPermissionNameConverter() {
        return permissionNameConverter;
    }

    /**
     * @param periodOpen
     *            the periodOpen to set
     */
    public void setPeriodOpen(final boolean periodOpen) {
        this.periodOpen = periodOpen;
    }

    /**
     * @return the periodOpen
     */
    public boolean isPeriodOpen() {
        return periodOpen;
    }

    public boolean isCanPersist() {

        if (periodOpen)
            return false;

        Collection<FeedbackPeriod> currentFeedbackPeriods = feedbackPeriodService.findAllFeedbackPeriodsForLastPeriod();

        for (FeedbackPeriod fp : currentFeedbackPeriods) {
            if (fp.getNewFinalBand() == null || fp.getNewFinalPosition() == null)
                return false;
        }

        return true;
    }

    public String persist() throws Exception {

        Collection<FeedbackPeriod> currentFeedbackPeriods = feedbackPeriodService.findAllFeedbackPeriodsForLastPeriod();

        for (FeedbackPeriod fp : currentFeedbackPeriods) {
            Employee emp = fp.getEmployee();
            JobFunction function = fp.getNewFinalBand();
            Long position = fp.getNewFinalPosition();
            JobTerm condition = null;

            Date today = new Date();

            CareerRole role = emp.createEmploymentConditionHistoryIfIsNull().getCurrentCareerRoles();

            if (role != null) {
                if (role.getCareerRole().equals(function) && role.getCareerRolePosition().equals(position)) {
                    continue;
                }
                condition = role.getCondition();
            } else {
                condition = emp.getCurrentStatus().getStatusType();
            }

            CareerRole newRole = new CareerRole();
            newRole.setCareerRole(function);
            newRole.setCareerRolePosition(position);
            newRole.setCondition(condition);
            newRole.setEffectiveDate(today);

            emp.createEmploymentConditionHistoryIfIsNull().getCareerRoles().add(newRole);
            emp.update(today);
        }

        return execute();
    }

}